4. 참조를 값으로 바꾸기

  • 분산시스템, 동시성 시스템에서 유용
  • 데이터를 갱신할 때 내부 객체를 통째로 대체해야 하는 경우

객체, 데이터의 불변성을 적용하면 사이드이펙트를 최소화할 수 있다.
다만 상황에 따라 가변객체를 사용하는 경우가 있으니 조심하자.

절차


  1. 후보 클레스가 불변인지, 불변이 될 수 있는지 확인한다.
  2. 각각의 setter를 하나씩 제거한다.
  3. 이 값 객체의 필드들을 사용하는 동치성 비교 메서드(equals)를 만든다.

예시 코드

😞 Before

class TelephoneNumber {
    constructor() {
        this._areaCode = ''
        this._number = ''
    }

    get areaCode() {
        return this._areaCode
    }

    set areaCode(arg) {
        this._areaCode = arg
    }

    get number() {
        return this._number
    }

    set number(arg) {
        this._number = arg
    }
}

class Person {
    constructor() {
        this._telephoneNumber = new TelephoneNumber()
    }

    get officeAreaCode() {
        return this._telephoneNumber.areaCode
    }

    set officeAreaCode(arg) {
        this._telephoneNumber.areaCode = arg
    }

    get officeNumber() {
        return this._telephoneNumber.number
    }

    set officeNumber(arg) {
        this._telephoneNumber.number = arg
    }
}

😃 After

class TelephoneNumber {
    constructor(areaCode, number) {
        this._areaCode = areaCode
        this._number = number
    }

    get areaCode() {
        return this._areaCode
    }

    set areaCode(arg) {
        this._areaCode = arg
    }

    get number() {
        return this._number
    }

    set number(arg) {
        this._number = arg
    }

    equals(other) {
        if (!(other instanceof TelephoneNumber)) {
            return false
        }
        return this.areaCode === other.areaCode && this.number === other.number
    }
}

class Person {
    constructor(areaCode, number) {
        this._telephoneNumber = new TelephoneNumber(areaCode, number)
    }

    get officeAreaCode() {
        return this._telephoneNumber.areaCode
    }

    set officeAreaCode(arg) {
        this._telephoneNumber = new TelephoneNumber(arg, this.officeNumber)
    }

    get officeNumber() {
        return this._telephoneNumber.number
    }

    set officeNumber(arg) {
        this._telephoneNumber = new TelephoneNumber(this.officeAreaCode, arg)
    }
}

results matching ""

    No results matching ""